package com.google.code.jholidays.events;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import org.junit.Test;

import com.google.code.jholidays.core.EventDescriptor;
import com.google.code.jholidays.moc.FixedEventMoc;

public class FloatingEventFactoryTest {

    @Test
    public void testDoesntMatch() {
	EventDescriptor descriptor = new EventDescriptor(1);
	descriptor.setExpression("123");

	FloatingEventFactory factory = new FloatingEventFactory();
	assertFalse(factory.matches(descriptor));
    }

    @Test
    public void testMatchesOne() {
	EventDescriptor descriptor = new EventDescriptor(1);
	descriptor.setExpression("1%Sun%Aug");

	FloatingEventFactory factory = new FloatingEventFactory();
	assertTrue(factory.matches(descriptor));
    }

    @Test
    public void testMatchesMany() {
	EventDescriptor descriptor = new EventDescriptor(1);
	FloatingEventFactory factory = new FloatingEventFactory();

	String[] daysOfWeek = new String[] { "Sun", "Mon", "Tue", "Wed", "Thu",
		"Fri", "Sat" };
	String[] months = new String[] { "Jan", "Feb", "Mar", "Apr", "May",
		"Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

	int maxOrder = 4;

	for (String month : months) {
	    for (String dayOfWeek : daysOfWeek) {
		for (int order = 1; order <= maxOrder; ++order) {
		    StringBuilder sb = new StringBuilder();
		    sb.append(order);
		    sb.append('%');
		    sb.append(dayOfWeek);
		    sb.append('%');
		    sb.append(month);

		    descriptor.setExpression(sb.toString());

		    assertTrue(factory.matches(descriptor));
		}
	    }
	}

    }

    @Test
    public void testAnalizeExpressionNoParent() {
	EventDescriptor descriptor = new EventDescriptor(1);
	FloatingEventFactory factory = new FloatingEventFactory();

	String[] daysOfWeek = new String[] { "Sun", "Mon", "Tue", "Wed", "Thu",
		"Fri", "Sat" };
	String[] months = new String[] { "Jan", "Feb", "Mar", "Apr", "May",
		"Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

	// String[] months = new String[] { "Dec" };

	int maxOrder = 4;

	for (String month : months) {
	    for (String dayOfWeek : daysOfWeek) {
		for (int order = 1; order <= maxOrder; ++order) {
		    StringBuilder sb = new StringBuilder();
		    sb.append(order);
		    sb.append('%');
		    sb.append(dayOfWeek);
		    sb.append('%');
		    sb.append(month);

		    descriptor.setExpression(sb.toString());

		    assertTrue(factory.matches(descriptor));
		    assertNotNull(factory.analizeExpression(descriptor, null));
		}
	    }
	}
    }

    @Test
    public void testAnalizeExpressionHasParent() {
	int parentID = 1;
	int eventID = 2;

	EventDescriptor descriptor = new EventDescriptor(eventID, parentID);
	IEvent parent = new FixedEventMoc(parentID);

	FloatingEventFactory factory = new FloatingEventFactory();

	String[] daysOfWeek = new String[] { "Sun", "Mon", "Tue", "Wed", "Thu",
		"Fri", "Sat" };
	String[] months = new String[] { "Jan", "Feb", "Mar", "Apr", "May",
		"Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

	// String[] months = new String[] { "Dec" };

	int maxOrder = 4;

	for (String month : months) {
	    for (String dayOfWeek : daysOfWeek) {
		for (int order = 1; order <= maxOrder; ++order) {
		    StringBuilder sb = new StringBuilder();
		    sb.append(order);
		    sb.append('%');
		    sb.append(dayOfWeek);
		    sb.append('%');
		    sb.append(month);

		    descriptor.setExpression(sb.toString());

		    assertTrue(factory.matches(descriptor));
		    assertNotNull(factory.analizeExpression(descriptor, parent));
		}
	    }
	}
    }

    @Test
    public void testFloatingEventFactory() {
	FloatingEventFactory factory = new FloatingEventFactory();
	assertNotNull(factory);
    }

    @Test
    public void testCreateEvent() {
	int parentID = 1;
	int eventID = 2;

	EventDescriptor descriptor = new EventDescriptor(eventID, parentID);
	IEvent parent = new FixedEventMoc(parentID);

	FloatingEventFactory factory = new FloatingEventFactory();

	String[] daysOfWeek = new String[] { "Sun", "Mon", "Tue", "Wed", "Thu",
		"Fri", "Sat" };
	String[] months = new String[] { "Jan", "Feb", "Mar", "Apr", "May",
		"Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

	// String[] months = new String[] { "Dec" };

	int maxOrder = 4;

	for (String month : months) {
	    for (String dayOfWeek : daysOfWeek) {
		for (int order = 1; order <= maxOrder; ++order) {
		    StringBuilder sb = new StringBuilder();
		    sb.append(order);
		    sb.append('%');
		    sb.append(dayOfWeek);
		    sb.append('%');
		    sb.append(month);

		    descriptor.setExpression(sb.toString());

		    assertTrue(factory.matches(descriptor));
		    assertNotNull(factory.createEvent(descriptor, parent));
		}
	    }
	}
    }
}
